package cn.kgm.makeGod;

import cn.kgm.makeGod.action.*;
import cn.kgm.makeGod.condition.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @Version 1.8
 * @Author: Kappi
 * @Date: 2025-9-11 11:16
 * @Description: cn.kgm.makeGod.MackGod
 */
public class GhostValleySimulation {

    public static void main(String[] args) {
        // 创建世界
        WorldState world = new WorldState();

        // 初始化地点
        WorldInitializer.initializeLocations(world);

        // 初始化物品
        WorldInitializer.initializeItems(world);

        // 初始化资源点
        WorldInitializer.initializeResourceNodes(world);

        List<Character> characters = RandomCharacterGenerator.generateRandomCharactersWithRelationships(3000);

        // 处理初始物品
        for (Character character : characters) {
            world.addCharacter(character);

            // 添加初始物品
            for (Map.Entry<Integer, Integer> entry : character.getInitialItems().entrySet()) {
                world.acquireItem(character.getId(), entry.getKey(), entry.getValue());
            }
        }
        // 随机分配位置
        for (Character character : characters) {
            Location initialLocation = RandomCharacterGenerator.decideNextLocation(character, world);
            character.setCurrentLocation(initialLocation);
        }

        // 添加角色到世界
        for (Character character : characters) {
            world.addCharacter(character);
        }

        // 设置事件
        GhostValleySimulation.setupEvents(world);

        // 模拟36个月
        System.out.println("===== 开始模拟世界（包含资源抢夺和战斗） =====");
        for (int i = 0; i < 1000; i++) {
            world.simulateMonth();

            // 每6个月输出一次世界状态
            if (i % 6 == 5) {
                printWorldStatus(world, i + 1);
            }

            // 每12个月让角色重新决策移动
            if (i % 12 == 11) {
                for (Character character : world.getCharacters().values()) {
                    Location newLocation = RandomCharacterGenerator.decideNextLocation(character, world);
                    if (!newLocation.equals(character.getCurrentLocation())) {
                        System.out.println(character.getName() + " 从 " +
                                character.getCurrentLocation().getName() +
                                " 移动到了 " + newLocation.getName());
                        character.setCurrentLocation(newLocation);
                    }
                }
            }
        }

        // 输出最终结果
        printFinalResults(world);
    }

    private static void setupEvents(WorldState world) {
        // 1. 原有的事件
        GameEvent flirtEvent = createFlirtEvent();
        GameEvent revengeEvent = createRevengeEvent();

        // 2. 新增事件：抢夺宝物
        GameEvent robEvent = new GameEvent(3, "杀人夺宝", 20);
        robEvent.getConditions().add(new LocationCondition(LocationType.WILD));
        robEvent.getConditions().add(new PersonalityCondition(PersonalityTag.EVIL, 60));
        robEvent.getConditions().add(new PersonalityCondition(PersonalityTag.SELFISH, 50));
        robEvent.getConditions().add(new BattleCondition(true));

        robEvent.getActions().add(new DialogueAction("#actor.name# 见财起意，想要抢夺 #target.name# 身上的宝物"));
        robEvent.getActions().add(new StartBattleAction(true));

        // 3. 新增事件：指点修炼
        GameEvent teachEvent = new GameEvent(4, "指点迷津", 15);
        teachEvent.getConditions().add(new RelationshipCondition(RelationshipType.FRIEND, 50, null));
        teachEvent.getConditions().add(new StatCondition("level", null, null) {
            @Override
            public boolean check(Character actor, Character target, WorldState world) {
                return actor.getLevel() > target.getLevel() + 3;
            }
        });

        teachEvent.getActions().add(new DialogueAction("#actor.name# 好心指点 #target.name# 修炼上的困惑"));
        teachEvent.getActions().add(new CultivateAction(true));

        // 4. 新增事件：赠送丹药
        GameEvent giftEvent = new GameEvent(5, "赠送丹药", 25);
        giftEvent.getConditions().add(new RelationshipCondition(RelationshipType.FRIEND, 40, null));
        giftEvent.getConditions().add(new PersonalityCondition(PersonalityTag.KIND, 50));

        giftEvent.getActions().add(new DialogueAction("#actor.name# 将一枚珍贵的丹药赠送给 #target.name#"));
        giftEvent.getActions().add(new ExchangeItemAction("丹药", false));

        // 5. 新增事件：请求材料
        GameEvent requestEvent = new GameEvent(6, "请求炼器材料", 20);
        requestEvent.getConditions().add(new RelationshipCondition(RelationshipType.FRIEND, 30, null));
        requestEvent.getConditions().add(new LocationCondition(LocationType.CITY));

        requestEvent.getActions().add(new DialogueAction("#actor.name# 向 #target.name# 请求一些炼器材料"));
        requestEvent.getActions().add(new ExchangeItemAction("材料", true));

        // 6. 新增事件：秘境探险
        GameEvent adventureEvent = new GameEvent(7, "秘境探险", 10);
        adventureEvent.getConditions().add(new LocationCondition(LocationType.DUNGEON));
        adventureEvent.getConditions().add(new RelationshipCondition(null, 20, null));

        adventureEvent.getActions().add(new DialogueAction("#actor.name# 和 #target.name# 在秘境中一起探险"));

        RollSuccessAction adventureRoll = new RollSuccessAction(50, "luck", 0.3);
        adventureRoll.getOnSuccess().add(new DialogueAction("两人合作无间，找到了珍贵的宝物"));
        adventureRoll.getOnSuccess().add(new CultivateAction(true));
        adventureRoll.getOnSuccess().add(new ChangeRelationshipAction(15));

        adventureRoll.getOnFailure().add(new DialogueAction("探险过程中遇到了危险，两人勉强逃脱"));
        adventureRoll.getOnFailure().add(new ChangeRelationshipAction(-5));

        adventureEvent.getActions().add(adventureRoll);

        // 7. 新增事件：因爱生恨
        GameEvent loveToHateEvent = new GameEvent(8, "因爱生恨", 5);
        loveToHateEvent.getConditions().add(new RelationshipCondition(RelationshipType.LOVER, 70, null));
        loveToHateEvent.getConditions().add(new PersonalityCondition(PersonalityTag.GRUDGE, 80));

        loveToHateEvent.getActions().add(new DialogueAction("#actor.name# 发现 #target.name# 与他人有染，由爱转恨"));
        loveToHateEvent.getActions().add(new ChangeRelationshipAction(-50));
        loveToHateEvent.getActions().add(new DialogueAction("#actor.name# 发誓要报复 #target.name#"));

        // 8. 新增事件：调解矛盾
        GameEvent mediateEvent = new GameEvent(9, "调解矛盾", 8);
        mediateEvent.getConditions().add(new RelationshipCondition(RelationshipType.SWORN_ENEMY, null, -30));
        mediateEvent.getConditions().add(new PersonalityCondition(PersonalityTag.KIND, 70));
        mediateEvent.getConditions().add(new StatCondition("charm", 70, null));

        mediateEvent.getActions().add(new DialogueAction("#actor.name# 试图调解与 #target.name# 的矛盾"));

        RollSuccessAction mediateRoll = new RollSuccessAction(40, "charm", 0.5);
        mediateRoll.getOnSuccess().add(new DialogueAction("调解成功，两人冰释前嫌"));
        mediateRoll.getOnSuccess().add(new ChangeRelationshipAction(40));

        mediateRoll.getOnFailure().add(new DialogueAction("调解失败，矛盾反而加深"));
        mediateRoll.getOnFailure().add(new ChangeRelationshipAction(-10));

        mediateEvent.getActions().add(mediateRoll);

        // 将所有事件添加到世界
        world.addEvent(flirtEvent);
        world.addEvent(revengeEvent);
        world.addEvent(robEvent);
        world.addEvent(teachEvent);
        world.addEvent(giftEvent);
        world.addEvent(requestEvent);
        world.addEvent(adventureEvent);
        world.addEvent(loveToHateEvent);
        world.addEvent(mediateEvent);
    }

    private static GameEvent createFlirtEvent() {
        GameEvent flirtEvent = new GameEvent(1, "风流才子遇佳人", 10);
        flirtEvent.getConditions().add(new LocationCondition(LocationType.CITY));
        flirtEvent.getConditions().add(new PersonalityCondition(PersonalityTag.PHILANDERER, 70));
        flirtEvent.getConditions().add(new StatCondition("charm", 80, null));

        flirtEvent.getActions().add(new DialogueAction("#actor.name# 被 #target.name# 的美貌迷住，上前搭讪。"));

        RollSuccessAction rollAction = new RollSuccessAction(30, "charm", 0.5);
        rollAction.getOnSuccess().add(new DialogueAction("两人相谈甚欢，关系更进一步。"));
        rollAction.getOnSuccess().add(new ChangeRelationshipAction(20));

        rollAction.getOnFailure().add(new DialogueAction("#target.name# 冷淡地拒绝了 #actor.name#。"));
        rollAction.getOnFailure().add(new ChangeRelationshipAction(-10));

        flirtEvent.getActions().add(rollAction);

        return flirtEvent;
    }

    private static GameEvent createRevengeEvent() {
        GameEvent revengeEvent = new GameEvent(2, "睚眦之怨", 50);
        revengeEvent.getConditions().add(new RelationshipCondition(RelationshipType.SWORN_ENEMY, null, -50));
        revengeEvent.getConditions().add(new PersonalityCondition(PersonalityTag.GRUDGE, 50));

        revengeEvent.getActions().add(new DialogueAction("#actor.name# 找到了仇人 #target.name# ，二话不说便动起手来！"));
        revengeEvent.getActions().add(new ChangeRelationshipAction(-10));

        return revengeEvent;
    }

    private static GameEvent createWineCompetitionEvent() {
        GameEvent wineEvent = new GameEvent(101, "万年蛇胎酒之争", 80);

        // 条件：在酒馆，且双方都有争抢的倾向
        wineEvent.getConditions().add(new LocationCondition(LocationType.TAVERN));
        wineEvent.getConditions().add(new Condition() {
            @Override
            public boolean check(Character actor, Character target, WorldState world) {
                // 至少一方有争抢倾向（邪恶、自私或风流）
                return actor.hasPersonality(PersonalityTag.EVIL, 40) ||
                        actor.hasPersonality(PersonalityTag.SELFISH, 40) ||
                        actor.hasPersonality(PersonalityTag.PHILANDERER, 60) ||
                        target.hasPersonality(PersonalityTag.EVIL, 40) ||
                        target.hasPersonality(PersonalityTag.SELFISH, 40) ||
                        target.hasPersonality(PersonalityTag.PHILANDERER, 60);
            }
        });

        // 动作：争抢逻辑
        wineEvent.getActions().add(new Action() {
            @Override
            public void execute(Character actor, Character target, WorldState world, EventResult result) {
                result.addLog(actor.getName() + " 和 " + target.getName() + " 同时看上了酒馆中的万年蛇胎酒!");

                // 决定争抢结果的因素：等级、攻击力、运气
                int actorPower = actor.getLevel() * 2 + actor.getAttack() + actor.getLuck() / 5;
                int targetPower = target.getLevel() * 2 + target.getAttack() + target.getLuck() / 5;

                // 性格影响：邪恶和自私的角色更有攻击性
                if (actor.hasPersonality(PersonalityTag.EVIL, 50)) actorPower += 15;
                if (actor.hasPersonality(PersonalityTag.SELFISH, 50)) actorPower += 10;
                if (target.hasPersonality(PersonalityTag.EVIL, 50)) targetPower += 15;
                if (target.hasPersonality(PersonalityTag.SELFISH, 50)) targetPower += 10;

                // 加入随机因素
                Random random = new Random();
                actorPower += random.nextInt(20);
                targetPower += random.nextInt(20);

                if (actorPower > targetPower) {
                    result.addLog(actor.getName() + " 成功抢到了万年蛇胎酒!");

                    // 获得物品
                    world.acquireItem(actor.getId(), 1, 1);

                    // 关系变化
                    adjustRelationship(actor, target, -25, world);

                } else {
                    result.addLog(target.getName() + " 成功守住了万年蛇胎酒!");

                    // 关系变化
                    adjustRelationship(actor, target, -15, world);
                }
            }

            private void adjustRelationship(Character source, Character target, int change, WorldState world) {
                Relationship rel = source.getRelationshipTo(target.getId());
                if (rel != null) {
                    rel.setValue(rel.getValue() + change);
                } else {
                    RelationshipType type = change < -20 ? RelationshipType.SWORN_ENEMY : RelationshipType.STRANGER;
                    source.addRelationship(new Relationship(source.getId(), target.getId(), type, change));
                }
            }
        });

        return wineEvent;
    }

    /**
     * 根据性格决定初始位置
     */
    private static Location determineInitialLocation(Character character) {
        Random random = new Random();
        LocationType preferredType;

        // 根据性格决定偏好位置
        if (character.hasPersonality(PersonalityTag.PHILANDERER, 50)) {
            preferredType = LocationType.TAVERN; // 风流的角色喜欢酒馆
        } else if (character.hasPersonality(PersonalityTag.LONER, 50)) {
            preferredType = LocationType.WILD; // 孤僻的角色喜欢野外
        } else if (character.hasPersonality(PersonalityTag.FAMILY, 50)) {
            preferredType = LocationType.CITY; // 重视家庭的角色喜欢城市
        } else {
            // 随机选择
            LocationType[] types = LocationType.values();
            preferredType = types[random.nextInt(types.length)];
        }

        // 简化实现：随机返回一个指定类型的地点
        // 在实际实现中，应该从WorldState中获取地点
        switch (preferredType) {
            case CITY:
                return new Location(1, "天元城", LocationType.CITY);
            case WILD:
                return new Location(2, "迷雾森林", LocationType.WILD);
            case DUNGEON:
                return new Location(3, "古修士洞府", LocationType.DUNGEON);
            case TAVERN:
                return new Location(5, "醉仙楼", LocationType.TAVERN);
            default:
                return new Location(1, "天元城", LocationType.CITY);
        }
    }

    /**
     * 打印世界状态
     */
    private static void printWorldStatus(WorldState world, int month) {
        System.out.println("\n=== 第 " + month + " 月世界状态 ===");

        // 打印资源点状态
        System.out.println("资源点状态:");
        for (ResourceNode node : world.getResourceNodes().values()) {
            String status = node.isAvailable() ? "可用" : "冷却中 (" + node.getCurrentTime() + "/" + node.getRespawnTime() + ")";
            System.out.println("  - " + node.getName() + " (" + node.getLocation().getName() + "): " + status);
        }

        // 打印角色物品持有情况
        System.out.println("\n角色物品持有:");
        for (Character character : world.getCharacters().values()) {
            List<ItemOwnership> items = world.getItemsOwnedBy(character.getId());
            if (!items.isEmpty()) {
                System.out.println("  - " + character.getName() + ":");
                for (ItemOwnership ownership : items) {
                    Item item = world.getItem(ownership.getItemId());
                    if (item != null) {
                        System.out.println("    * " + item.getName() + " x" + ownership.getQuantity());
                    }
                }
            }
        }

        // 打印角色等级排名
        System.out.println("\n角色等级排名:");
        List<Character> sortedCharacters = new ArrayList<>(world.getCharacters().values());
        sortedCharacters.sort((c1, c2) -> Integer.compare(c2.getLevel(), c1.getLevel()));

        for (int i = 0; i < Math.min(5, sortedCharacters.size()); i++) {
            Character character = sortedCharacters.get(i);
            System.out.println("  " + (i + 1) + ". " + character.getName() +
                    " (等级 " + character.getLevel() +
                    ", 战斗力 " + ResourceCompetitionSystem.calculateCombatPower(character) + ")");
        }

        // 打印角色关系网络
        System.out.println("\n重要关系变化:");
        int relationshipChangeCount = 0;
        for (Character character : world.getCharacters().values()) {
            for (Relationship rel : character.getRelationships().values()) {
                if (rel.getValue() <= -50) { // 只显示敌对关系
                    Character target = world.getCharacter(rel.getTargetId());
                    if (target != null) {
                        System.out.println("  - " + character.getName() + " 与 " + target.getName() +
                                " 是仇敌 (关系值: " + rel.getValue() + ")");
                        relationshipChangeCount++;
                    }
                }
            }
        }

        if (relationshipChangeCount == 0) {
            System.out.println("  - 暂无重要敌对关系");
        }
    }

    /**
     * 打印最终结果
     */
    private static void printFinalResults(WorldState world) {
        System.out.println("\n===== 模拟结束 - 最终结果 =====");

        // 存活角色统计
        System.out.println("存活角色: " + world.getCharacters().size() + "人");

        // 最富有的角色（物品价值最高）
        System.out.println("\n最富有的角色:");
        List<Character> sortedByWealth = new ArrayList<>(world.getCharacters().values());
        sortedByWealth.sort((c1, c2) -> {
            int wealth1 = calculateWealth(world, c1);
            int wealth2 = calculateWealth(world, c2);
            return Integer.compare(wealth2, wealth1);
        });

        for (int i = 0; i < Math.min(3, sortedByWealth.size()); i++) {
            Character character = sortedByWealth.get(i);
            int wealth = calculateWealth(world, character);
            System.out.println("  " + (i + 1) + ". " + character.getName() + " (财富值: " + wealth + ")");
        }

        // 最强大的角色
        System.out.println("\n最强大的角色:");
        List<Character> sortedByPower = new ArrayList<>(world.getCharacters().values());
        sortedByPower.sort((c1, c2) -> Integer.compare(
                ResourceCompetitionSystem.calculateCombatPower(c2),
                ResourceCompetitionSystem.calculateCombatPower(c1)
        ));

        for (int i = 0; i < Math.min(3, sortedByPower.size()); i++) {
            Character character = sortedByPower.get(i);
            int power = ResourceCompetitionSystem.calculateCombatPower(character);
            System.out.println("  " + (i + 1) + ". " + character.getName() + " (战斗力: " + power + ")");
        }

        // 最受欢迎的角色（朋友最多）
        System.out.println("\n最受欢迎的角色:");
        List<Character> sortedByPopularity = new ArrayList<>(world.getCharacters().values());
        sortedByPopularity.sort((c1, c2) -> Integer.compare(
                countFriends(c2), countFriends(c1)
        ));

        for (int i = 0; i < Math.min(3, sortedByPopularity.size()); i++) {
            Character character = sortedByPopularity.get(i);
            int friends = countFriends(character);
            System.out.println("  " + (i + 1) + ". " + character.getName() + " (朋友数: " + friends + ")");
        }

        // 最孤独的角色（敌人最多）
        System.out.println("\n最孤独的角色:");
        List<Character> sortedByEnemies = new ArrayList<>(world.getCharacters().values());
        sortedByEnemies.sort((c1, c2) -> Integer.compare(
                countEnemies(c2), countEnemies(c1)
        ));

        for (int i = 0; i < Math.min(3, sortedByEnemies.size()); i++) {
            Character character = sortedByEnemies.get(i);
            int enemies = countEnemies(character);
            System.out.println("  " + (i + 1) + ". " + character.getName() + " (敌人数: " + enemies + ")");
        }
    }

    /**
     * 计算角色财富
     */
    private static int calculateWealth(WorldState world, Character character) {
        int wealth = 0;
        for (ItemOwnership ownership : world.getItemsOwnedBy(character.getId())) {
            Item item = world.getItem(ownership.getItemId());
            if (item != null) {
                wealth += item.getValue() * ownership.getQuantity();
            }
        }
        return wealth;
    }

    /**
     * 计算朋友数量
     */
    private static int countFriends(Character character) {
        int count = 0;
        for (Relationship rel : character.getRelationships().values()) {
            if (rel.getType() == RelationshipType.FRIEND && rel.getValue() > 30) {
                count++;
            }
        }
        return count;
    }

    /**
     * 计算敌人数量
     */
    private static int countEnemies(Character character) {
        int count = 0;
        for (Relationship rel : character.getRelationships().values()) {
            if (rel.getType() == RelationshipType.SWORN_ENEMY && rel.getValue() < -30) {
                count++;
            }
        }
        return count;
    }

}
